#!/bin/bash

#############################################################################################
# 用途: inotify 同步脚本
# 作者: 丁辉
# 更新时间: 2024-03-28
#############################################################################################

# rsync 服务端 IP
HOST=none
# rsync 用户名
USER=rsync
# rsync 密码文件
PASSWORD=/etc/rsync.pass
# 同步目录
SRC=/data/
# rsync 模块
Module=data
# inotifywait 命令
inotifywait=/usr/bin/inotifywait

#### Inotifywait 参数解释
# -m: 监控目录
# -r: 递归监控
# -q: 静默模式
# --timefmt: 时间格式
    # %Y: 年
    # %m: 月
    # %d: 日
    # %H: 时
    # %M: 分
# --format: 输出格式
    # %T: 时间
    # %w: 目录
    # %f: 文件
    # %e: 事件
    # %Xe: 扩展事件
# -e: 监控事件
    # modify: 文件内容修改
    # delete: 文件删除
    # create: 文件创建
    # attrib: 文件属性修改
    # move: 文件移动
    # close_write: 文件关闭写入

##### Rsync 参数解释
# -a: 归档模式，表示以递归方式传输文件，并保持所有文件属性，等于-rlptgoD
# -r: 相对路径传输文件
# -t: 保持文件时间信息
# -u: 仅传输更新文件
# -z: 传输时压缩
# -v: 详细模式输出
# -c: 跳过校验算法，仅根据文件时间和大小判断是否同步
# -P: 保持文件传输进度

# 监控目录
cd $SRC

$inotifywait -mrq --timefmt '%Y%m%d %H:%M' --format '%T %w%f %Xe' -e modify,delete,create,attrib,move,close_write ./ \
| while read files ;do
    # 获取文件路径
    FILE_PWD=$(echo $files | awk '{print $3}')
    # 获取文件事件
    FILE_EVENT=$(echo $files | awk '{print $4}')
    # 在日志内提示时间
    echo ".....................................$(date)....................................."

    # 增加、修改、写入完成、移动进事件
    if [[ $FILE_EVENT =~ "CREATE" ]] || [[ $FILE_EVENT =~ "MODIFY" ]] || [[ $FILE_EVENT =~ "CLOSE_WRITE" ]] || [[ $FILE_EVENT =~ "MOVED_TO" ]]; then
        rsync -artuz --password-file=${PASSWORD} $(dirname ${FILE_PWD}) ${USER}@${HOST}::${Module}
    fi
    
    # 删除、移动事件触发
    if [[ $FILE_EVENT =~ "DELETE" ]] || [[ $FILE_EVENT =~ "MOVED_FROM" ]]; then
        rsync -artuz --password-file=${PASSWORD} $(dirname ${FILE_PWD}) ${USER}@${HOST}::${Module}
    fi

    # 修改属性事件触发[ touch, chgrp, chmod, chown ]
    if [[ $FILE_EVENT =~ "ATTRIB" ]]; then
        # 判断是否为目录, 如果是目录则不同步(在目录下文件修改属性时, 目录属性也会被修改)
        if [ ! -d "$INO_FILE" ]; then
            rsync -artuz --password-file=${PASSWORD} $(dirname ${FILE_PWD}) ${USER}@${HOST}::${Module}
        fi
    fi
done